package entities.concept;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import entities.vocabulary.Display;

/**
 * And concepts: a set of concepts in conjunction
 * @author j55wu
 *
 */
public class AndConcept extends Concept{

	private final HashSet<Concept> cons;
	
	// TODO: hack to preserve order in toString()
	private Concept c1;
	private Concept c2;
	
	public AndConcept(Set<Concept> in){
		 this.cons = new HashSet<Concept>();
		 this.cons.addAll(in);
	}
	
	public AndConcept(Concept c1, Concept c2) {
		this.cons = new HashSet<Concept>();
		this.cons.add(c1);
		this.cons.add(c2);
		
		this.c1 = c1;
		this.c2 = c2;
	}

	public AndConcept(List<Concept> cs) {
		this.cons = new HashSet<Concept>();
		this.cons.addAll(cs);
	}

	public HashSet<Concept> getConceptSet(){
		return this.cons;
	}

	/*@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		for(Concept c:cons){
			result = prime * result + ((c == null) ? 0 : c.hashCode());
		}
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!(obj instanceof AndConcept))
			return false;
		AndConcept that = (AndConcept) obj;
		if (cons == null) {
			if (that.cons != null)
				return false;
		} else if (!cons.equals(that.cons))
			return false;
		return true;
	}*/
	
	@Override
	public String toString() {
		if (c1 != null && c2 != null && cons.size() <= 2) {
			return "["+c1.toString() + " "+Display.ANDUNICODE+" " + c2.toString()+"]";
		}
		
		
		StringBuilder sb = new StringBuilder();
		sb.append("[");
		Iterator<Concept> iter = cons.iterator();
		while (iter.hasNext()) {
			Concept n = iter.next();
			if (n == null) {
				System.err.println("WARNING: Null entry in AND concept");
				continue;
			}
			sb.append(n.toString());
			if (iter.hasNext()) {
				sb.append(" "+Display.ANDUNICODE+" " );
			}
		}
		sb.append("]");
		return sb.toString();
	}

	@Override
	public Concept getPrimeCopy() {
		HashSet<Concept> ns = new HashSet<Concept>();
		for (Concept c : this.cons) {
			ns.add(c.getPrimeCopy());
		}
		return new AndConcept(ns);
	}
}
